<?php
// +----------------------------------------------------------------------
// | INPHP
// | Copyright (c) 2023 https://inphp.cc All rights reserved.
// | Licensed ( https://opensource.org/licenses/MIT )
// | Author: 幺月儿(https://gitee.com/lulanyin) Email: inphp@qq.com
// +----------------------------------------------------------------------
// | 账户管理
// +----------------------------------------------------------------------
namespace app\sso\http\api\admin;

use app\sso\model\UserBindModel;
use app\sso\model\UserModel;
use Inphp\Core\Db\Db;
use Inphp\Core\Db\PDO\Query;
use Inphp\Core\Object\Message;
use Inphp\Core\Util\Arr;
use Inphp\Core\Util\Str;

#[\app\admin\attributes\auth(null, true)] class user
{
    public int $uid = 0;


    public function index(): Message
    {
        $uid = GET("uid");
        $uid = is_numeric($uid) && $uid > 0 ? $uid : 0;
        if ($uid <= 0) {
            return httpMessage("UID参数无效");
        }

        $item = UserModel::emptyQuery("u")
            ->leftJoin(UserModel::tableName()." p", "u.parentUid=p.uid")
            ->select([
                "u.*",
                "p.username as parentUsername, p.phone as parentPhone, p.countryCode as parentCountryCode, p.nickname as parentNickname, p.face as parentFace, p.admin as parentAdmin, p.state as parentState"
            ])
            ->where("u.uid", $uid)->first();
        if (empty($item)) {
            return httpMessage("未找到账号数据");
        }
        $item['nickname'] = UserModel::decodeNickname($item['nickname']);
        $item['parentNickname'] = UserModel::decodeNickname($item['parentNickname']);
        $item['face'] = attachmentUrl($item['face']);
        $item['parentFace'] = attachmentUrl($item['parentFace']);
        $item['thirdPartyList'] = !empty($item['thirdPartyList']) ? explode(",", $item['thirdPartyList']) : [];
        Arr::unsetKey($item, [
            "password", "sp", "pwdKey"
        ]);
        return httpMessage($item);
    }

    /**
     * 获取账户列表
     * @return array
     */
    public function list(): array
    {
        //查询
        $db = UserModel::emptyQuery("u");

        //账户状态
        $state = GET("state");
        $state = $state == 1 || $state == 2 || $state == 3 || $state == '0' ? $state : null;
        if (!is_null($state)) {
            $db->where("u.state", $state);
        }

        //搜索
        $keyword = GET("keyword");
        $keyword = !empty($keyword) ? Str::trim($keyword) : null;
        if (!empty($keyword)) {
            if (is_numeric($keyword) && strlen($keyword) < 12) {
                //数字，查询手机号码
                $db->whereLike("u.phone", "%{$keyword}%");
            } else {
                //其它，查询昵称
                $db->where(function(Query $q) use($keyword) {
                    $q->whereLike("u.username", "%{$keyword}%")
                        ->orWhereLike("from_base64(substr(u.nickname, 23))", "%{$keyword}%");
                });
            }
        }

        //分组
        $groups = GET("groups");
        if (!empty($groups)) {
            $db->whereNumberInSet($groups, "u.groups");
        }

        //标签
        $labels = GET("labels");
        if (!empty($labels)) {
            $db->whereNumberInSet($labels, "u.labels");
        }

        //绑定了某些平台
        $binds = GET("binds");
        $binds = !empty($binds) ? Str::trim($binds) : "";
        $binds = !empty($binds) ? explode(",", $binds) : [];
        if (!empty($binds)) {
            $numberList = [];
            foreach ($binds as $number) {
                if (!empty($number) && !in_array(ceil($number), $numberList)) {
                    $numberList[] = $number;
                }
            }
            if (!empty($numberList)) {
                $db->whereIsIntersection("u.thirdPartyList", $numberList);
            }
        }

        //是否是超级管理员
        $admin = GET("admin");
        $admin = $admin == 1 || $admin == '0' ? $admin : null;
        if (!is_null($admin)) {
            $db->where("u.admin", $admin);
        }

        //关联查询推荐人
        $db->leftJoin(UserModel::tableName()." p", "u.parentUid=p.uid")
            ->select([
                "u.*",
                "p.username as parentUsername, p.phone as parentPhone, p.countryCode as parentCountryCode, p.nickname as parentNickname, p.face as parentFace, p.admin as parentAdmin, p.state as parentState"
            ]);

        //行数
        $rows = $db->rows();
        //当前页数
        $page = GET('page', 1);
        $page = is_numeric($page) && $page > 0 ? ceil($page) : 1;
        //总页数
        $pages = 1;
        //列表数据
        $list = [];
        if ($rows > 0) {
            $total = GET("total", 30);
            $total = is_numeric($total) && $total > 2 ? $total : 30;
            $pages = ceil($rows / $total);
            $page = $page > $pages ? $pages : $page;
            $offset = $total * ($page - 1);
            $list = $db->orderBy("u.uid", "desc")->get($total, $offset);
            foreach ($list as &$item)
            {
                $item['nickname'] = UserModel::decodeNickname($item['nickname']);
                $item['parentNickname'] = UserModel::decodeNickname($item['parentNickname']);
                $item['face'] = attachmentUrl($item['face']);
                $item['parentFace'] = attachmentUrl($item['parentFace']);
                $item['thirdPartyList'] = !empty($item['thirdPartyList']) ? explode(",", $item['thirdPartyList']) : [];
            }
        }
        //返回列表数据，包含行数、页码、总页数、数据列表
        return compact("rows", "page", "pages", "list");
    }

    /**
     * 保存分组/标签
     * @return Message
     */
    public function setFilter(): Message
    {
        $uid = POST("uid");
        $uid = is_numeric($uid) && $uid > 0 ? ceil($uid) : 0;
        if ($uid <= 0) {
            return httpMessage("UID参数无效");
        }

        $name = POST("name");
        $name = $name == "group" || $name == "label" ? $name : null;
        if (is_null($name)) {
            return httpMessage("参数无效");
        }

        $value = POST("value");
        $value = is_array($value) ? join(",", $value) : $value;
        $value = !empty($value) ? Str::trim($value) : "";
        $values = !empty($value) ? explode(",", $value) : [];

        //过滤数值
        $idList = [];
        foreach ($values as $id) {
            if (is_numeric($id) && $id > 0 && !in_array(ceil($id), $idList)) {
                $idList[] = ceil($id);
            }
        }
        $trueValue = [];
        if (!empty($idList)) {
            //取有效数值
            $list = Db::from("sso_{$name}")->whereIn("id", $idList)->get();
            if (!empty($list)) {
                foreach ($list as $item) {
                    $trueValue[] = $item["id"];
                }
                sort($trueValue);
            }
        }

        $db = UserModel::emptyQuery()
            ->where("uid", $uid)
            ->set($name."s", !empty($trueValue) ? join(",", $trueValue) : null);
        if ($db->update()) {
            return httpMessage(0, "保存成功");
        }
        return httpMessage("保存设置失败");
    }

    /**
     * 保存账户/新建账户
     * @return Message
     */
    public function save(): Message
    {
        //用户名
        $username = POST("username");
        $username = !empty($username) ? Str::trim($username) : null;
        if (empty($username)) {
            return httpMessage("缺少用户名");
        }
        if (strlen($username) < 6 || strlen($username) > 30) {
            return httpMessage("用户名至少6个字符，且不可超过30个字符");
        }
        //UID
        $uid = POST("uid");
        $uid = is_numeric($uid) && $uid > 0 ? ceil($uid) : 0;
        //检测合法性
        if (!UserModel::checkUsername($username, $uid)) {
            return httpMessage("用户名无法使用，请更换！");
        }
        //国家代码
        $countryCode = POST("countryCode");
        if (!empty($countryCode)) {
            if (stripos($countryCode, "+") === 0) {
                $countryCode = substr($countryCode, 1);
            }
        }
        //默认使用中国号码
        $countryCode = is_numeric($countryCode) && $countryCode >= 0 ? $countryCode : 86;
        //手机号码
        $phone = POST("phone");
        if (!empty($phone) && !Str::isPhoneNumber($phone, $countryCode)) {
            return httpMessage("手机号码格式错误");
        }
        //昵称
        $nickname = POST("nickname");
        $nickname = !empty($nickname) ? $nickname : $username;
        if (empty($nickname)) {
            return httpMessage("缺少昵称");
        }
        if (mb_strlen($nickname) > 30) {
            return httpMessage("昵称长度请控制在30个字符内");
        }
        //管理员
        $admin = POST("admin");
        $admin = $admin == 1;

        $data = [
            "username"      => $username,
            "nickname"      => UserModel::encodeNickname($nickname),
            "phone"         => !empty($phone) ? $phone : null,
            "countryCode"   => $countryCode
        ];
        //管理员属性，仅允许帮他人账户修改
        if ($this->uid != $uid) {
            $data["admin"] = $admin ? 1 : 0;
        }
        //开始处理数据
        $db = UserModel::emptyQuery();
        if ($uid > 0) {
            $db->where("uid", $uid);
            if ($db->update($data)) {
                return httpMessage(0, "资料修改成功");
            }
        } else {
            $data["ip"]     = getIP();
            if ($db->insert($data)) {
                return httpMessage(0, "账号创建成功");
            }
        }
        return httpMessage("保存数据失败");
    }

    /**
     * 修改指定账号的状态
     * @return Message
     */
    public function setState(): Message
    {
        //不可标记当前管理员账号
        $uid = POST("uid");
        $uid = is_numeric($uid) && $uid > 0 ? ceil($uid) : 0;
        if ($uid <= 0) {
            return httpMessage("缺少UID参数");
        }
        $state = POST("state");
        $state = $state == 1 || $state == 2 || $state == 3 || $state == '0' ? $state : null;
        if (is_null($state)) {
            return httpMessage("状态参数无效");
        }
        if ($this->uid == $uid) {
            return httpMessage("不可修改当前账号状态");
        }
        $db = UserModel::emptyQuery()
            ->where("uid", $uid)
            ->set("state", $state);
        if ($db->update()) {
            return httpMessage(0, "修改状态成功");
        }
        return httpMessage("修改状态失败");
    }

    /**
     * 修改密码
     * @return Message
     */
    public function setFace(): Message
    {
        //不可标记当前管理员账号
        $uid = POST("uid");
        $uid = is_numeric($uid) && $uid > 0 ? ceil($uid) : 0;
        if ($uid <= 0) {
            return httpMessage("缺少UID参数");
        }
        //头像
        $face = POST("face");
        $face = !empty($face) ? parseUploadFilesUrl($face) : null;
        $face = is_array($face) ? $face[0] : $face;
        $db = UserModel::emptyQuery()->where("uid", $uid)
            ->set([
                "face"  => $face
            ]);
        if ($db->update()) {
            return httpMessage(0, "修改成功");
        }
        return httpMessage("修改失败");
    }

    /**
     * 修改密码
     * @return Message
     */
    public function setPassword(): Message
    {
        //不可标记当前管理员账号
        $uid = POST("uid");
        $uid = is_numeric($uid) && $uid > 0 ? ceil($uid) : 0;
        if ($uid <= 0) {
            return httpMessage("缺少UID参数");
        }
        $type = POST("type", "login");
        $type = $type == "sp" ? "sp" : "login";
        $password = POST("password");
        $password = !empty($password) ? $password : null;
        if (empty($password)) {
            return httpMessage("缺少密码");
        }

        if (strlen($password) < 6 || strlen($password) > 16) {
            return httpMessage("密码长度请控制在6~16个字符间");
        }
        $db = UserModel::emptyQuery()->where("uid", $uid);
        //开始修改
        if ($type == "login") {
            list($password, $pwdKey) = UserModel::hashLoginPassword($password);
            $db->set([
                "password"      => $password,
                "pwdKey"        => $pwdKey
            ]);
        } else {
            $db->set("sp", UserModel::hashSP($password, $uid));
        }
        if ($db->update()) {
            return httpMessage(0, "修改成功");
        }
        return httpMessage("修改失败");
    }

}